<?php
header("Content-type: text/html; charset=gbk");
include_once "HttpUtil.php";
include_once "Constant.php";
//Needed model file
include_once $_SERVER['DOCUMENT_ROOT']."/model/User.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Task.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Template.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Stage.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Location.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/User.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Undertake.php";
include_once $_SERVER['DOCUMENT_ROOT']."/model/Application.php";
//Needed dao file
include_once $_SERVER['DOCUMENT_ROOT']."/dao/TaskDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/TemplateDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/StageDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/LocationDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/UserDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/UndertakeDAO.php";
include_once $_SERVER['DOCUMENT_ROOT']."/dao/ApplicationDAO.php";

/**
 * Created by PhpStorm.
 * User: lwh
 * Date: 2017/7/24
 * Time: 15:07
 */
//接收post数据，并强制转换为关联数组
$data = $_POST['data'];
$para = json_decode($data,true);
$result = getRecommendedTask($para);

echo urldecode(json_encode($result));

function getRecommendedTask($para){
    //输入参数
    $userId = $para["userid"];
    $latitude = $para["latitude"];
    $longitude = $para["longitude"];
    //返回结果集
    $responses = array();
    //The DAO of task, Template, User and Location
    $taskDAO = new TaskDAO();
    $templateDAO = new TemplateDAO();
    $stageDAO = new StageDAO();
    $locationDAO = new LocationDAO();
    $userDAO = new UserDAO();
    $undertakeDAO = new UndertakeDAO();
    $appDAO = new ApplicationDAO();
    // Data distributed in Task(all information of Task)，Template(stageNum) and Location(longitude and latitude)
    $tasks = $taskDAO->queryAllTask();
    //根据user类型返回对应类型的任务
    $user = $userDAO->query($userId);
    //默认不需要有限制，返回所有符合条件的任务集合
    $needConstraint = false;
    //如果是普通用户，需要限制：只能返回userType为0的任务集合
    if($user->getTag() == User::$USER_NORMAL){
        $needConstraint = true;
    }

    foreach ($tasks as $task){
        if($task->getUserId() != $userId && $task->getStatus() == TASK::$STATUS_ONGOING){
            $stage = $stageDAO->queryStageByTaskAndIndex($task->getId(),$task->getCurrentStage());
            if($stage != null){
                $undertake = $undertakeDAO->queryByUserAndStage($userId,$stage->getId());
                $application = $appDAO->queryByUserAndStage($userId,$stage->getId());
                if($undertake == null && $application == null && isIdle($stage)){
                    $response = new ResponseBO();
                    $currentDest = $locationDAO->queryByStageAndType($stage->getId(),Location::$TYPE_DEST);
                    $time = calTime($longitude,$latitude,$currentDest);
					$isWithin = compareTime($time,$stage->getDeadline());
                    if($isWithin){
                        $response->setId($task->getId());
                        $response->setTemplateId($task->getTemplateId());
                        $response->setUserId($task->getUserId());
                        //设置requester的账户名
                        $requester = $userDAO->query($task->getUserId());
                        $response->setRequester($requester->getAccount());
                        $response->setTaskTitle($task->getTitle());
                        $response->setStageDesc($stage->getDescription());
                        $response->setStageReward($stage->getReward());
                        //设置进度
                        $template = $templateDAO->query($task->getTemplateId());
                        $response->setProgress($task->getCurrentStage()."/".$template->getTotalStageNum());
                        $response->setCurrentStage($task->getCurrentStage());
                        $response->setBonusReward($task->getBonusReward());
                        $response->setPublishTime($task->getPublishTime());
                        $response->setDeadline($task->getDeadline());
                        $response->setLongitude($currentDest->getLongitude());
                        $response->setLatitude($currentDest->getLatitude());
                        //设置contract
                        if($template->getTotalStageNum() > 1){
                            $time = $time + Constant::$TIME_EXTRA_FOR_WORKER * 60;//额外预留时间，默认为10分钟
                            $contractMillionSec = microtime() + $time * 1000;
                            $contract = date('Y-m-d H:i:s',$contractMillionSec);
                            //因为额外预留了十分钟，可能导致契约时间超过ddl，这里做一个比较和选择
                            if($contractMillionSec > strtotime($stage->getDeadline()))
                                $contract = $stage->getDeadline();
                            $response->setStageContract($contract);
                        }
                        else
                            $response->setStageContract($task->getDeadline());

                        //VIP用户，返回所有符合条件任务集合
                        if(!$needConstraint)
                            array_push($responses,$response);
                        //普通用户，只返回userType为0的任务集合
                        else if($needConstraint && $task->getUserType()== User::$USER_NORMAL)
                            array_push($responses,$response);
                    }
                }
            }
        }
    }

    return $responses;
}

//判断是否空闲：未过期的undertake数量是否等于所需worker数量
function isIdle($stage){
    $isIdle = true;
    $undertakeDAO = new UndertakeDAO();
    $workerNum = $stage->getWorkerNum();
    $undertakes = $undertakeDAO->queryByStage($stage->getId());
    $currentNum = 0;
    foreach ($undertakes as $undertake){
        if($undertake->getStatus() != -1)
            $currentNum++;
    }
    if($currentNum == $workerNum)
        $isIdle = false;
    return $isIdle;
}

//计算时间预估
function calTime($longitude,$latitude,$currentDest){
    $result = json_decode(HttpUtil::doGet($latitude,$longitude,$currentDest->getLatitude(),$currentDest->getLongitude()),true);
    if($result["status"] == 0){
        $result = $result["result"][0];
        $time = $result["duration"]["value"];
        return $time;
    }
    return -1;
}

//计算是否能够在ddl之前完成任务
function compareTime($time,$ddl) {
    $isWithin = true;
    //计算时间差
    $milliseconds = strtotime($ddl) - microtime();
    $seconds = $milliseconds / 1000;
    if($seconds < $time)
        $isWithin = false;
    return $isWithin;
}


class ResponseBO{
    public $id;
    public $templateId;
    public $userId;
    public $requester;
    public $taskTitle;
    public $stageDesc;
    public $stageReward;
    public $progress;
    public $currentStage;
    public $bonusReward;
    public $publishTime;
    public $deadline;
    public $longitude;
    public $latitude;
    public $stageContract;

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param mixed $id
     */
    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getTemplateId()
    {
        return $this->templateId;
    }

    /**
     * @param mixed $templateId
     */
    public function setTemplateId($templateId)
    {
        $this->templateId = $templateId;
    }

    /**
     * @return mixed
     */
    public function getUserId()
    {
        return $this->userId;
    }

    /**
     * @param mixed $userId
     */
    public function setUserId($userId)
    {
        $this->userId = $userId;
    }

    /**
     * @return mixed
     */
    public function getRequester()
    {
        return $this->requester;
    }

    /**
     * @param mixed $requester
     */
    public function setRequester($requester)
    {
        $this->requester = urlencode ($requester);
    }

    /**
     * @return mixed
     */
    public function getTaskTitle()
    {
        return $this->taskTitle;
    }

    /**
     * @param mixed $taskTitle
     */
    public function setTaskTitle($taskTitle)
    {
        $this->taskTitle = urlencode ($taskTitle);
    }

    /**
     * @return mixed
     */
    public function getStageDesc()
    {
        return $this->stageDesc;
    }

    /**
     * @param mixed $stageDesc
     */
    public function setStageDesc($stageDesc)
    {
        $this->stageDesc = urlencode ($stageDesc);
    }

    /**
     * @return mixed
     */
    public function getStageReward()
    {
        return $this->stageReward;
    }

    /**
     * @param mixed $stageReward
     */
    public function setStageReward($stageReward)
    {
        $this->stageReward = $stageReward;
    }

    /**
     * @return mixed
     */
    public function getProgress()
    {
        return $this->progress;
    }

    /**
     * @param mixed $progress
     */
    public function setProgress($progress)
    {
        $this->progress = $progress;
    }

    /**
     * @return mixed
     */
    public function getCurrentStage()
    {
        return $this->currentStage;
    }

    /**
     * @param mixed $currentStage
     */
    public function setCurrentStage($currentStage)
    {
        $this->currentStage = $currentStage;
    }

    /**
     * @return mixed
     */
    public function getBonusReward()
    {
        return $this->bonusReward;
    }

    /**
     * @param mixed $bonusReward
     */
    public function setBonusReward($bonusReward)
    {
        $this->bonusReward = $bonusReward;
    }

    /**
     * @return mixed
     */
    public function getPublishTime()
    {
        return $this->publishTime;
    }

    /**
     * @param mixed $publishTime
     */
    public function setPublishTime($publishTime)
    {
        $this->publishTime = $publishTime;
    }

    /**
     * @return mixed
     */
    public function getDeadline()
    {
        return $this->deadline;
    }

    /**
     * @param mixed $deadline
     */
    public function setDeadline($deadline)
    {
        $this->deadline = $deadline;
    }

    /**
     * @return mixed
     */
    public function getLongitude()
    {
        return $this->longitude;
    }

    /**
     * @param mixed $longitude
     */
    public function setLongitude($longitude)
    {
        $this->longitude = $longitude;
    }

    /**
     * @return mixed
     */
    public function getLatitude()
    {
        return $this->latitude;
    }

    /**
     * @param mixed $latitude
     */
    public function setLatitude($latitude)
    {
        $this->latitude = $latitude;
    }

    /**
     * @return mixed
     */
    public function getStageContract()
    {
        return $this->stageContract;
    }

    /**
     * @param mixed $stageContract
     */
    public function setStageContract($stageContract)
    {
        $this->stageContract = $stageContract;
    }


}
?>
